package com.lt.lumentracks.service.Impl;

import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.lt.lumentracks.constant.JwtClaimsConstant;
import com.lt.lumentracks.entity.dto.user.UserAddDTO;
import com.lt.lumentracks.entity.dto.user.UserDTO;
import com.lt.lumentracks.entity.dto.user.UserLoginDTO;
import com.lt.lumentracks.entity.dto.user.UserUpdateDTO;
import com.lt.lumentracks.entity.po.User;
import com.lt.lumentracks.entity.vo.common.PageVO;
import com.lt.lumentracks.entity.vo.common.Result;
import com.lt.lumentracks.entity.vo.user.UserVO_conversationList;
import com.lt.lumentracks.entity.vo.user.UserVO_info;
import com.lt.lumentracks.entity.vo.user.UserVO_post;
import com.lt.lumentracks.entity.vo.user.UserVO_profile;
import com.lt.lumentracks.mapper.UserMapper;
import com.lt.lumentracks.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lt.lumentracks.utils.AliOSSUtils;
import com.lt.lumentracks.utils.jwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户基础信息表 服务实现类
 * </p>
 *
 * @author swl
 * @since 2025-07-07
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private AliOSSUtils aliOSSUtils;


    // 添加用户
    @Override
    public Result<Integer> addUser(UserAddDTO addDTO) {
        if(addDTO.getPhone().isEmpty() && addDTO.getEmail().isEmpty()){
            return Result.error("请使用手机号或邮箱任一进行注册");
        }
        if(addDTO.getPhone().isEmpty()){
            addDTO.setPhone(null);
        }
        if(addDTO.getEmail().isEmpty()){
            addDTO.setEmail(null);
        }

        User user = new User();
        user.setCreateTime(LocalDateTime.now());
        BeanUtils.copyProperties(addDTO, user);

        boolean res = this.save(user);
        if (!res) {
            return Result.error("添加失败");
        }
        return Result.success(user.getId()); // 主键返回
    }


    // 删除用户
    @Override
    public Result<String> delUserById(Integer id) {
        return this.removeById(id) ? Result.success("删除成功") : Result.error("删除失败");
    }


    // 修改用户
    @Override
    public Result<String> updateUserById(UserUpdateDTO updateDTO) {
        User user = new User();
        user.setUpdateTime(LocalDateTime.now());
        BeanUtils.copyProperties(updateDTO, user);
        boolean res = this.updateById(user);
        if (!res) {
            return Result.error("修改失败");
        }
        return Result.success("修改成功");
    }

    // 修改用户头像
    @Override
    @Transactional
    public Result<String> updateAvatar(Integer uid, String avatarUrl) throws ClientException {
        User u = lambdaQuery().eq(User::getId, uid).one();

        // 如果有旧的头像，则删除
        if (u.getAvatarUrl() != null) {
            aliOSSUtils.deleteObject(u.getAvatarUrl());
        }

        boolean res = lambdaUpdate().eq(User::getId, uid)
                .set(User::getAvatarUrl, avatarUrl)
                .update();
        return res ? Result.success("修改成功") : Result.error("修改失败");
    }


    // 获取所有用户
    @Override
    public Result<List<User>> getAllUser() {
        List<User> list = this.list();
        return Result.success(list);
    }

    // 分页查询所有用户
    @Override
    public PageVO<User> getAllUserByPage(long current, long size) {
        Page<User> p = new Page<>(current, size);
        p.addOrder(OrderItem.desc("create_time"));   // 按时间降序排列，最新的排在最前

        Page<User> page_MP = this.page(p); // 使用mp自带的方法，获取分页数据
        return PageVO.of(page_MP); // 将分页数据转为自定义的vo
    }

    // 条件查询用户
    @Override
    public PageVO<User> getInCondition(UserDTO userDTO) {

        // 1.创建实体类对象
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);

        // 2.创建分页对象
        Page<User> pageInstance = new Page<>(userDTO.getCurrent(), userDTO.getSize());

        // 3.创建mybatisPlus分页对象
        Page<User> page_MP = lambdaQuery()
                // 3.1 构建查询条件
                .eq(user.getId() != null, User::getId, user.getId())
                .like(user.getUsername() != null, User::getUsername, user.getUsername())
                .eq(user.getEmail() != null, User::getEmail, user.getEmail())
                .eq(user.getPhone() != null, User::getPhone, user.getPhone())
                .eq(user.getPassword() != null, User::getPassword, user.getPassword())
                .eq(user.getGender() != null, User::getGender, user.getGender())
                .eq(user.getLocation() != null, User::getLocation, user.getLocation())
                .eq(user.getStatus() != null, User::getStatus, user.getStatus())
                .orderByDesc(User::getCreateTime)

                .page(pageInstance); // 3.2应用分页

        // 4.返回自定义的分页对象
        return PageVO.of(page_MP);
    }

    // 根据id查询用户--返回部分信息（其他用户个人主页查询业务用）
    @Override
    public UserVO_profile getById_ProfileQuery(Integer id) {
        UserVO_profile vo = new UserVO_profile();
        User user = this.getById(id);
        if (user == null) {
            vo.setId(-1);
            vo.setUsername("账号已注销");
            return vo;
        }
        BeanUtils.copyProperties(user, vo);
        return vo;
    }

    // 根据id查询用户--返回部分信息（查询帖子业务用）
    @Override
    public UserVO_post getById_PostQuery(Integer id) {
        UserVO_post vo = new UserVO_post();
        User user = this.getById(id);
        if (user == null) {
            vo.setId(-1);
            vo.setUsername("账号已注销");
            return vo;
        }
        BeanUtils.copyProperties(user, vo);
        return vo;
    }

    // 根据id查询用户--返回部分信息（查询会话列表业务用）
    @Override
    public List<UserVO_conversationList> getById_ConvListQuery(List<Integer> ids) {
        // 查询用户
        List<User> users = lambdaQuery().in(User::getId, ids).list();

        // 按 id 传入顺序构造 VO 列表
        Map<Integer, User> userMap = users.stream().collect(Collectors.toMap(User::getId, Function.identity())); // 构造 id -> user 的映射
        List<UserVO_conversationList> vo = new ArrayList<>();
        for (Integer id : ids) {
            User user = userMap.get(id);
            if (user != null) {
                UserVO_conversationList vo_conv = new UserVO_conversationList();
                BeanUtils.copyProperties(user, vo_conv);
                vo.add(vo_conv);
            }
        }
        return vo;
    }


    // 用户登录（返回jwt令牌）
    @Override
    public Result<String> login(UserLoginDTO dto) {
        if(dto.getPhone() == null && dto.getEmail() == null){
            return Result.error("请输入完整信息");
        }

        User user = lambdaQuery()
                    .eq(dto.getPhone() != null && !dto.getPhone().trim().isEmpty(), User::getPhone, dto.getPhone())
                    .eq(dto.getEmail() != null && !dto.getEmail().trim().isEmpty(), User::getPassword, dto.getPassword())
                    .eq(dto.getPassword() != null && !dto.getPassword().trim().isEmpty(), User::getPassword, dto.getPassword())
                    .one();

        if(user == null){
            return Result.error("账号或密码错误！");
        }
        if(user.getStatus() == 0){
            return Result.error("该账号封禁中！");
        }

        // 封装数据
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, user.getId());
        claims.put(JwtClaimsConstant.USERNAME, user.getUsername());
        claims.put(JwtClaimsConstant.PHONE, user.getPhone());
        claims.put(JwtClaimsConstant.EMAIL, user.getEmail());

        String jwt;
        try {
            jwt = jwtUtils.GenerateJwt(claims);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        //返回jwt令牌
        return Result.success(jwt);
    }


    // 根据jwt令牌返回用户具体信息
    @Override
    public UserVO_info getUserInfoByJwt(String jwt) {
        // 解析令牌
        Map<String, Object> claims;
        try {
            claims = jwtUtils.ParseJwt(jwt);
        } catch (Exception e) {
            return null;
        }

        // 从中取出用户id
        Long id = Long.valueOf(claims.get("id").toString());

        // 根据id查询用户
        User user = this.getById(id);

        // 处理数据
        UserVO_info vo = new UserVO_info();
        BeanUtils.copyProperties(user, vo);

        // 返回数据
        return vo;
    }



}
